package be.nepherte.movmanager.client.ui;

import java.util.List;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

import be.nepherte.movmanager.client.MovManager;
import be.nepherte.movmanager.client.ui.components.AbstractMoviesView;
import be.nepherte.movmanager.client.ui.components.SearchPanel;
import be.nepherte.movmanager.client.ui.tabframework.Tab;
import be.nepherte.movmanager.client.util.MoviesViewFactory;
import be.nepherte.movmanager.client.util.MoviesViewFactory.MoviesViewType;
import be.nepherte.movmanager.domain.Movie;
import be.nepherte.movmanager.domain.UserInfo;

/**
 * This class represents the Search tab of MovManager. This page allows the
 * user to search a movie in his/her movie collection.
 * 
 * <p>
 * Copyright © 2010 Bart Verhoeven
 * </p>
 * 
 * <p>
 * This file is part of MovManager.
 * </p>
 * 
 * <p>
 * MovManager is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * </p>
 * 
 * <p>
 * MovManager is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * </p>
 * 
 * <p>
 * You should have received a copy of the GNU General Public License along with
 * MovManager. If not, see http://www.gnu.org/licenses/.
 * </p>
 * 
 * @author 	Dieter Sauvillers, Bart Verhoeven
 * @version	0.1
 */

public class SearchTab extends Tab{
	 /**Main panel holding all other panels.*/
	 private final VerticalPanel pnlMain = new VerticalPanel();
	 /**Top panel holding all panels located at the top.*/
	 private final HorizontalPanel pnlTop = new HorizontalPanel();
	 /**Panel holding a particular MoviesView.*/
	 private final VerticalPanel pnlMovies = new VerticalPanel();
	 /**Panel holding the search settings.*/
	 private SearchPanel pnlSearch = new SearchPanel();
	 /**Wrapper panel holding the navigation elements and search panel.*/
	 private final HorizontalPanel pnlSearchAndNavigation = new HorizontalPanel();
	 /**User info of the current user.*/
	 private final UserInfo userInfo;
	 /**A collection matched movies.*/
	 private List<Movie> matchedMovies;
	 /**currently active movies view.*/
	 private AbstractMoviesView moviesView;
	 
	
	 /**
     * Creates, initializes and return SearchTab.
     * 
     * @param	userInfo
     * 			user info of the current user
     */
	public static TabInfo init(final UserInfo userInfo) {
		
		
		return new TabInfo(MovManager.constants.SearchTabName(), MovManager.constants.SearchTabDescription(), MovManager.constants.SearchTabColor()) {	
			@Override
			public Tab createInstance() {
				return new SearchTab(userInfo);
			}
		};
	}
	
	/**
	 * Creates a new SearchTab. To create an object of this class, use
	 * {@link #init()}.
	 * 
	 * @param	userInfo
	 * 			the user info of the current user
	 */
	private SearchTab(UserInfo userInfo) {
		super();
		initMainPanel();
		this.userInfo = userInfo;
	}
	
	/**
	 * Initializes the main panel.
	 */
	private void initMainPanel() {
		initializeTopPanel();
		formatMainPanel();
		initializeMoviesView(MoviesViewFactory.createMoviesView(MoviesViewType.MovieListView));
		pnlMain.add(pnlTop);
		pnlMain.add(pnlMovies);
		initWidget(pnlMain);
	}
	
	/**
	 * Initializes the movies view.
	 * 
	 * @param	moviesView
	 * 			the new movies view
	 */
	private void initializeMoviesView(AbstractMoviesView moviesView) {
		// note: GWT SDK API specifically states widgets only implement HasClickHandlers so cast is safe
		Widget leftNavigationElement = (Widget) moviesView.getLeftNavigationElement();
		Widget rightNavigationElement = (Widget) moviesView.getRightNavigationElement();
		
		// set the navigation arrows of the new view
		pnlSearchAndNavigation.insert(leftNavigationElement, 0);
		pnlSearchAndNavigation.add(rightNavigationElement);
		pnlSearchAndNavigation.setCellVerticalAlignment(leftNavigationElement, HasVerticalAlignment.ALIGN_MIDDLE);
		pnlSearchAndNavigation.setCellVerticalAlignment(rightNavigationElement, HasVerticalAlignment.ALIGN_MIDDLE);
		this.moviesView = moviesView;
	}
	
	/**
	 *Formats the main panel.
	 */
	private void formatMainPanel() {
		pnlMain.setWidth("100%");
		pnlMain.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
	}
	
	/**
	 * Initializes the top panel.
	 */
	private void initializeTopPanel() {
		formatTopPanel();
		initializeSearchPanel();	
	}
	
	/**
	 * Formats the top panel.
	 */
	private void formatTopPanel() {
		pnlTop.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
		pnlTop.setWidth("100%");
	}
	
	
	/**
	 * Initializes the filter panel and the navigational elements.
	 */
	private void initializeSearchPanel() {
		pnlSearchAndNavigation.add(pnlSearch);
		//add click handler search button
		pnlSearch.setFilterAction(new ClickHandler() {	
			@Override
			public void onClick(ClickEvent event) {
				matchedMovies = pnlSearch.searchMovies(userInfo.getMovies());
				pnlMovies.clear();
				
				if (matchedMovies.isEmpty()) {
					Label noMovies = new Label("No movies matched your search query.");
					noMovies.addStyleName("boldStyle");
					pnlMovies.add(noMovies);
				}
				else {
					moviesView.setMovies(matchedMovies);
					pnlMovies.add(moviesView);
				}
			}
		});
		
		// Add filter and navigation panel to top panel
		pnlTop.add(pnlSearchAndNavigation);
		pnlTop.setCellHorizontalAlignment(pnlSearchAndNavigation, HasHorizontalAlignment.ALIGN_CENTER);
	}
	
	@Override
	public void onShow() {
		pnlMovies.clear();
		pnlSearch.reset();
	}

	@Override
	public void onHide() {
	}
}